package com.lin.http.helloworld;

import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.codec.http.*;
import io.netty.util.AsciiString;

public class HttpHelloWorldServerHandler extends ChannelInboundHandlerAdapter {
	private static final byte[] CONTENT = {'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd'};

	// 也是一个字符串，它被编码到字符编码中，其字符总是使用一个字节，类似于ASCII。
	// 它在内部将其内容保存在byte数组中，这与字符串不同，后者使用字符数组，
	// 以减少内存占用，并更快地从byte数组和ByteBuffer等字节数据结构中传送数据。
	// 它通常与需要CharSequence的Header一起使用。
	private static final AsciiString CONTENT_TYPE = AsciiString.of("Content-Type");
	private static final AsciiString CONTENT_LENGTH = AsciiString.of("Content-Length");
	private static final AsciiString CONNECTION = AsciiString.of("Connection");
	private static final AsciiString KEEP_ALIVE = AsciiString.of("keep-alive");

	@Override
	public void channelRead(ChannelHandlerContext ctx, Object msg) {
		if (msg instanceof HttpRequest) {
			HttpRequest req = (HttpRequest) msg;

			boolean keepAlive = HttpUtil.isKeepAlive(req);
			FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK, Unpooled.copiedBuffer(CONTENT));
			response.headers().set(CONTENT_TYPE, "text/plain");
			response.headers().setInt(CONTENT_LENGTH, response.content().readableBytes());

			if (!keepAlive) {
				ctx.write(response).addListener(ChannelFutureListener.CLOSE);
			}else {
				response.headers().set(CONNECTION, KEEP_ALIVE);
				ctx.write(response);
			}
		}
	}

	@Override
	public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
		ctx.flush();
	}

	@Override
	public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
		cause.printStackTrace();
		ctx.close();
	}
}
